package storage.buffer;

import Common.GlobalConst;
import storage.data.Page;
import exceptions.DBBufferFull;
import exceptions.DBWritePageException;


public class SecondChance extends Replacer {
	
	public SecondChance ( BufferMgr bm ) {
		super ( bm ) ; 
	}
	
	@Override
	public synchronized int pickPage() throws DBBufferFull, DBWritePageException  {
		Slot [] pool = bufMan.pool ; 
		for ( int i = head ; i < head + BUFFER_SIZE * 2 ; i ++ ) {
			if ( pool [ i % BUFFER_SIZE ].state == Slot.free ) {
				pool [ i%BUFFER_SIZE].pin();
				clean ( i % BUFFER_SIZE ) ;
				head = ( i  + 1 ) % BUFFER_SIZE ; 
				return  i % BUFFER_SIZE ;
			}
			else if ( pool [ i % BUFFER_SIZE ].state == Slot.referenced ) pool[i%BUFFER_SIZE].state = Slot.free ;
		}
		
		throw new DBBufferFull () ; 
	}
	
	private void clean ( int slot ) throws DBWritePageException {
		Slot [] pool = bufMan.pool ; 
		if ( pool [ slot ].pid == Page.INVALID_PAGE ) return ;
		//Global.BufferManage.map.remove( pool [ slot ].pid ) ;
		if ( pool [ slot ].dirty )  {
			if ( bufMan.buff[ slot ] == null ) bufMan.buff [ slot ] = new byte [ GlobalConst.PAGESIZE ] ; 
			Page aPage = new Page ( bufMan.buff [ slot ]) ; 
			bufMan.writePage( pool [ slot].pid , aPage ) ;
		}
	}

}
